package zy.controller.wx;


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;

import zy.controller.BaseController;
import zy.entity.wx.component.T_Wx_Component;
import zy.service.wx.component.ComponentService;
import zy.util.DateUtil;
import zy.util.WeixinUtil;

@Controller
public class WxController extends BaseController{
	
	@Autowired
	private ComponentService componentService;
	
	@RequestMapping(value = "to_auth", method = RequestMethod.GET)
	public String to_auth() {
		return "auth/auth";
	}
	@RequestMapping(value = "redirect_auth", method = RequestMethod.GET)
	public void redirect_auth(HttpServletResponse resp) throws IOException {
		resp.sendRedirect(MessageFormat.format(WeixinUtil.component_login_page_url,
						WeixinUtil.my_app_id,
						componentService.getPreAuthCode(),
						WeixinUtil.auth_redirect_uri));
	}
	
	@RequestMapping(value = "receive_ticket", method = { RequestMethod.GET, RequestMethod.POST })
	@ResponseBody
	public String receive_ticket(
			@RequestParam("timestamp") String timestamp,
			@RequestParam("nonce")String nonce,
            @RequestParam("msg_signature")String msgSignature,
            @RequestBody String postData) {
		try {
			//把xml里的AppId手动替换成ToUserName再试一次
			postData = postData.replaceAll("AppId", "ToUserName");
			WXBizMsgCrypt pc = new WXBizMsgCrypt(WeixinUtil.my_token, WeixinUtil.my_encoding_aes_key, WeixinUtil.my_app_id);
			String result = pc.decryptMsg(msgSignature, timestamp, nonce,postData);
			Map<String, String> resultMap = xmlToMap(result);
			T_Wx_Component component = new T_Wx_Component();
			component.setWc_appid(resultMap.get("AppId"));
			component.setWc_createtime(DateUtil.timestampToDate(resultMap.get("CreateTime")+"000"));
			component.setWc_verify_ticket(resultMap.get("ComponentVerifyTicket"));
			componentService.update(component);
		} catch (AesException e) {
			e.printStackTrace();
		}catch (Exception e) {
			e.printStackTrace();
		}
		return "success";
	}

	public static Map<String, String> xmlToMap(String strXML) throws Exception {
		try {
			Map<String, String> data = new HashMap<String, String>();
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
			InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
			Document doc = documentBuilder.parse(stream);
			doc.getDocumentElement().normalize();
			NodeList nodeList = doc.getDocumentElement().getChildNodes();
			for (int idx = 0; idx < nodeList.getLength(); ++idx) {
				Node node = nodeList.item(idx);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					Element element = (Element) node;
					data.put(element.getNodeName(), element.getTextContent());
				}
			}
			try {
				stream.close();
			} catch (Exception ex) {
			}
			return data;
		} catch (Exception ex) {
			throw ex;
		}
	}

	@RequestMapping(value = "get_component_access_token", method = { RequestMethod.GET, RequestMethod.POST })
	@ResponseBody
	public Object getComponentAccessToken() {
		return ajaxSuccess(componentService.getComponentAccessToken());
	}
	
	@RequestMapping(value = "get_pre_auth_code", method = { RequestMethod.GET, RequestMethod.POST })
	@ResponseBody
	public Object getPreAuthCode() {
		return ajaxSuccess(componentService.getPreAuthCode());
	}

	/**
	* 根据auth_code查询授权信息
	* @param authCode 授权成功时获得的授权码
	* @param expiresIn 存活时间
	* @return
	*/
	@ResponseBody
	@RequestMapping(value = "queryAuth")
	public String queryAuth(@RequestParam("auth_code")String authCode, @RequestParam("expires_in")String expiresIn){
	    componentService.queryAuth(authCode, expiresIn);
	    return "success";
	}
	
}
